import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  CallHandler,
  HttpStatus,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { ResponseCode, getCodeMessage } from '../types/response-code.enum';
import { ApiResponse, createSuccessResponse } from '../types/response.types';

/**
 * 统一响应格式拦截器
 * 自动将控制器返回的数据包装成统一的响应格式
 */
@Injectable()
export class ResponseInterceptor<T> implements NestInterceptor<T, ApiResponse<T>> {
  intercept(context: ExecutionContext, next: CallHandler): Observable<ApiResponse<T>> {
    const request = context.switchToHttp().getRequest();
    const path = request.url;

    return next.handle().pipe(
      map((data) => {
        // 如果数据已经是 ApiResponse 格式，直接返回
        if (data && typeof data === 'object' && 'code' in data) {
          return {
            ...data,
            timestamp: data.timestamp || Date.now(),
            path: data.path || path,
          };
        }

        // 否则包装成成功响应
        return createSuccessResponse(data, '操作成功');
      }),
    );
  }
}

/**
 * 错误响应拦截器
 * 用于捕获异常并返回统一的错误响应格式
 */
@Injectable()
export class ErrorResponseInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const request = context.switchToHttp().getRequest();
    const path = request.url;

    return next.handle().pipe(
      map((data) => {
        // 处理成功响应
        if (data && typeof data === 'object' && 'code' in data) {
          return {
            ...data,
            timestamp: data.timestamp || Date.now(),
            path: data.path || path,
          };
        }

        // 包装普通数据为成功响应
        return createSuccessResponse(data, '操作成功');
      }),
    );
  }
}

/**
 * 创建标准HTTP状态码到自定义状态码的映射
 */
export const createHttpStatusMapping = () => {
  const mapping: Record<number, ResponseCode> = {
    [HttpStatus.BAD_REQUEST]: ResponseCode.BAD_REQUEST,
    [HttpStatus.UNAUTHORIZED]: ResponseCode.UNAUTHORIZED,
    [HttpStatus.FORBIDDEN]: ResponseCode.FORBIDDEN,
    [HttpStatus.NOT_FOUND]: ResponseCode.NOT_FOUND,
    [HttpStatus.METHOD_NOT_ALLOWED]: ResponseCode.METHOD_NOT_ALLOWED,
    [HttpStatus.CONFLICT]: ResponseCode.CONFLICT,
    [HttpStatus.UNPROCESSABLE_ENTITY]: ResponseCode.UNPROCESSABLE_ENTITY,
    [HttpStatus.TOO_MANY_REQUESTS]: ResponseCode.TOO_MANY_REQUESTS,
    [HttpStatus.INTERNAL_SERVER_ERROR]: ResponseCode.INTERNAL_SERVER_ERROR,
    [HttpStatus.NOT_IMPLEMENTED]: ResponseCode.NOT_IMPLEMENTED,
    [HttpStatus.BAD_GATEWAY]: ResponseCode.BAD_GATEWAY,
    [HttpStatus.SERVICE_UNAVAILABLE]: ResponseCode.SERVICE_UNAVAILABLE,
    [HttpStatus.GATEWAY_TIMEOUT]: ResponseCode.GATEWAY_TIMEOUT,
  };

  return mapping;
};

/**
 * 根据HTTP状态码获取对应的自定义状态码
 * @param httpStatus HTTP状态码
 * @returns 自定义状态码
 */
export function getResponseCodeFromHttpStatus(httpStatus: number): ResponseCode {
  const mapping = createHttpStatusMapping();
  return mapping[httpStatus] || ResponseCode.INTERNAL_SERVER_ERROR;
}
